package com.sc.nft.controller;

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.DesensitizedUtil;
import cn.hutool.core.util.ObjectUtil;
import com.meta.component.base.api.CommonResult;
import com.sc.nft.annotation.UserLogin;
import com.sc.nft.annotation.WithoutSign;
import com.sc.nft.controller.request.*;
import com.sc.nft.controller.vo.InviteUserVO;
import com.sc.nft.controller.vo.TransferAccountsMinVO;
import com.sc.nft.controller.vo.UserTelVO;
import com.sc.nft.controller.vo.VerificationUserInfoExistCapitalPassWordVO;
import com.sc.nft.dao.DaoIdentityDao;
import com.sc.nft.dao.StaticDataDao;
import com.sc.nft.dao.UserCreatorInfoDao;
import com.sc.nft.dao.UserInfoDao;
import com.sc.nft.entity.DaoIdentity;
import com.sc.nft.entity.UserCollection;
import com.sc.nft.entity.UserInfo;
import com.sc.nft.entity.dto.UserTelGetUserInfoDTO;
import com.sc.nft.entity.vo.*;
import com.sc.nft.enums.RedisKeyEnum;
import com.sc.nft.enums.SendSMSEnum;
import com.sc.nft.exception.GlobalException;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.pool.UserPool;
import com.sc.nft.service.CheckParameterService;
import com.sc.nft.service.UserInfoService;
import com.sc.nft.sup.ErrorCode;
import com.sc.nft.sup.PageRequest;
import com.sc.nft.sup.PageResult;
import com.sc.nft.sup.Result;
import com.sc.nft.vo.HwCheckVO;
import com.sc.nft.vo.ShuJuBaoFaceCheckVO;
import com.sc.nft.vo.ShuJuBaoFaceGetInitVO;
import com.sc.nft.vo.ShuJuBaoLiveDetectionVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.validation.Valid;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 服务控制器
 *
 * @author Sun
 * @description 由 Mybatisplus Code Generator 创建
 * @since 2022-05-29 10:36:55
 */
@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/user")
@Api(tags = "用户")
public class UserInfoController {

    private final UserInfoService userInfoService;
    private final CheckParameterService checkParameterService;
    private final UserInfoDao userInfoDao;
    private final DaoIdentityDao daoIdentityDao;
    private final UserCreatorInfoDao userCreatorInfoDao;
    private final StaticDataDao staticDataDao;
    private final Redisson redisson;
    private final RestTemplate restTemplate;

//    @ApiOperation(value = "注册", notes = "注册", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
//    @PostMapping(value = "/registeUser", produces = MediaType.APPLICATION_JSON_VALUE)
//    public Result<UserLoginVO> registeUser(@Valid @RequestBody RegisterUserRequest registerUserRequest, HttpServletRequest request) throws GlobalException {
//        String remoteHost = ServletUtil.getClientIP(request);
//        String key = "USER_REG_IP:" + remoteHost;
//        Object o = redisTemplate.opsForValue().get(key);
//        if (ObjectUtil.isNotNull(o) && Integer.parseInt(o.toString()) > 10) {
//            return Result.fail("注册账号超过限制");
//        }
//
//        checkParameterService.CheckVerificationcode(registerUserRequest.getUserAccount(),
//                registerUserRequest.getSmsId(),
//                registerUserRequest.getCodes(),
//                SendSMSEnum.REGISTER.getCode());
//
//        UserLoginVO userLoginVO = userInfoService.registeUser(registerUserRequest.getInviteCode(),
//                registerUserRequest.getTypes(),
//                registerUserRequest.getUserAccount(),
//                registerUserRequest.getPwd()
//        );
//        redisTemplate.opsForValue().increment(key);
//        DateTime now = DateTime.now();
//        long between = DateUtil.between(now, DateUtil.endOfDay(now), DateUnit.SECOND);
//        redisTemplate.expire(key, between, TimeUnit.SECONDS);
//        return Result.success(userLoginVO);
//    }

    @ApiOperation(value = "修改资金密码", notes = "修改资金密码", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/saveCapital", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result saveCapital(@Valid @RequestBody UserCapitalPassRequest registerUserRequest) throws GlobalException {
        checkParameterService.CheckVerificationcode(registerUserRequest.getUserAccount(),
                registerUserRequest.getSmsId(),
                registerUserRequest.getCodes(),
                SendSMSEnum.SETUP_PAY_PASSWORD.getCode());
        // 修改密码.只set一个新的支付密码其他不改变.
        userInfoDao.updateTransactionPassword(UserPool.getUser().getId(), registerUserRequest.getPwd());
        return Result.success();
    }

    @ApiOperation(value = "验证用户是否存在支付交易密码.", notes = "验证用户是否存在支付交易密码.", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/verificationUserInfoExistCapitalPassWord", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result verificationUserInfoExistCapitalPassWord() throws GlobalException {
        return Result.success(new VerificationUserInfoExistCapitalPassWordVO(userInfoService.verificationUserInfoExistCapitalPassWord()));
    }

    @ApiOperation(value = "登录", notes = "登录", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/login", produces = MediaType.APPLICATION_JSON_VALUE)
    @WithoutSign
    public Result<UserLoginVO> login(@Valid @RequestBody UserLoginRequest userLoginRequest) throws GlobalException {
//        String key = "USER_LOGIN_LOCK:" + userLoginRequest.getUserAccount();
//        Object o = redisTemplate.opsForValue().get(key);
//        if (ObjectUtil.isNotNull(o) && Integer.parseInt(o.toString()) > 5) {
//            return Result.fail("密码尝试次数过多，请稍后再试");
//        }
//        UserLoginVO login = null;
//        try {
//            login = userInfoService.login(userLoginRequest.getUserAccount(), userLoginRequest.getPwd());
//        } catch (GlobalRunTimeException e) {
//            Long increment = redisTemplate.opsForValue().increment(key);
//            redisTemplate.expire(key, 10 * 60, TimeUnit.SECONDS);
//            throw e;
//        }
//
//
//        return Result.success(login);

        String url = "http://meta-user-service/web/v1/meta/user/login_by_pwd";

        CommonResult<Map<String, Object>> result = restTemplate.postForObject(url, userLoginRequest, CommonResult.class);

        if (result == null || !result.isSuccessful()) {
            return Result.fail("登录失败");
        }

        Map<String, Object> data = result.getData();

        UserLoginVO vo = new UserLoginVO();
        vo.setUserId(((Number) data.get("userId")).longValue());
        vo.setUuid((String) data.get("uuid"));
        vo.setToken((String) data.get("token"));

        return Result.success(vo);
    }

    @ApiOperation(value = "通过token获取用户手机号", notes = "通过token获取用户手机号", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping("/getUserInfoByToken")
    @WithoutSign
    public Result<UserInfoVO> getUserInfoByToken(@RequestBody GetUserInfoByTokenRequest getUserInfoByTokenRequest) throws GlobalException {
        Object userId = null;
        try {
            userId = StpUtil.getLoginIdByToken(getUserInfoByTokenRequest.getToken());
            log.info("getUserInfoByToken userId: {}", userId);
            Long userIdLong = Long.parseLong((String) userId);
            return Result.success(userInfoService.getUserInfoById(userIdLong));
        } catch (NotLoginException e) {
            // 处理 token 无效或不存在的情况
            log.info("Token 无效或用户未登录 userId {}",userId);
            return Result.fail("Token 无效或用户未登录");
        }
    }


    @ApiOperation(value = "短信验证码登录", notes = "短信验证码登录", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/loginByUserTel", produces = MediaType.APPLICATION_JSON_VALUE)
    @WithoutSign
    public Result<UserLoginVO> loginByUserTel(@Valid @RequestBody UserLoginByTelRequest request) {
//        UserLoginVO login = userInfoService.login(request.getUserTel(), request.getCode(), request.getSmsId());
//        return Result.success(login);

        String url = "http://meta-user-service/web/v1/meta/user/login_by_sms";

        CommonResult<Map<String, Object>> result = restTemplate.postForObject(url, request, CommonResult.class);

        if (result == null || !result.isSuccessful()) {
            return Result.fail("登录失败");
        }

        Map<String, Object> data = result.getData();

        UserLoginVO vo = new UserLoginVO();
        vo.setUserId(((Number) data.get("userId")).longValue());
        vo.setUuid((String) data.get("uuid"));
        vo.setToken((String) data.get("token"));

        return Result.success(vo);
    }

    @ApiOperation(value = "用户邀请页", notes = "用户邀请页", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/getUserInvitePage", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<UserInviteVO> getUserInvitePage() {
        return Result.success(userInfoService.getUserInvitePage());
    }

    @ApiOperation(value = "查看邀请详情", notes = "查看邀请详情", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/getInviteDetails", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<ArrayList<UserInviteDetails>> getInviteDetails() {
        return Result.success(userInfoService.getInviteDetails());
    }

//    @ApiOperation(value = "修改个人信息", notes = "修改个人信息", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
//    @PostMapping(value = "/updateUserMaterial", produces = MediaType.APPLICATION_JSON_VALUE)
//    @UserLogin
//    public Result updateUserMaterial(@Valid @RequestBody UpdateUserMaterialRequest updateUserMaterialRequest) {
//
//        userInfoService.updateUserMaterial(updateUserMaterialRequest.getNickName(),
//                updateUserMaterialRequest.getAvatarImg(),
//                updateUserMaterialRequest.getBackGroundImg(), updateUserMaterialRequest.getBriefIntroduction());
//        return Result.success();
//    }

//    @ApiOperation(value = "修改登陆密码", notes = "修改登陆密码", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
//    @PostMapping(value = "/updateUserPassWord", produces = MediaType.APPLICATION_JSON_VALUE)
//    @UserLogin
//    public Result updateUserPassWord(@Valid @RequestBody UpdateUserPassWordRequest updateUserPassWordRequest) {
//        userInfoService.updateUserPassWord(updateUserPassWordRequest.getOnePwd(),
//                updateUserPassWordRequest.getTwoPwd(),
//                updateUserPassWordRequest.getOldPwd());
//        return Result.success();
//    }

//    @ApiOperation(value = "忘记密码", notes = "忘记密码", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
//    @PostMapping(value = "/forgetUserPassWord", produces = MediaType.APPLICATION_JSON_VALUE)
//    public Result forgetUserPassWord(@Valid @RequestBody ForgetUserPassWordRequest forgetUserPassWordRequest) {
//        String key = "USER_FORGET_PWD_LOCK:" + forgetUserPassWordRequest.getUserAccount();
//        Long increment = redisTemplate.opsForValue().increment(key);
//        if(increment>5){
//            return Result.fail("尝试次数过多，请稍后再试");
//        }
//        redisTemplate.expire(key, 10*60,TimeUnit.SECONDS);
//        userInfoService.forgetUserPassWord(forgetUserPassWordRequest.getCodes(),
//                forgetUserPassWordRequest.getSmsId(),
//                forgetUserPassWordRequest.getOnePwd(),
//                forgetUserPassWordRequest.getTwoPwd(),
//                forgetUserPassWordRequest.getUserAccount());
//        return Result.success();
//    }

    @ApiOperation(value = "获取实名认证状态-脱敏", notes = "获取实名认证状态-脱敏", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/getCertificationType", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<GetCertificationTypeVO> putCertification() {
        return Result.success(userInfoService.getCertificationType());
    }

    @ApiOperation(value = "实名验证提交", notes = "实名验证提交", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/putCertification", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
//    @Authentication
    public Result<SubmitRealNameVO> putCertification(@Valid @RequestBody PutCertificationRequest putCertificationRequest) throws IOException {
        putCertificationRequest.setCardId(putCertificationRequest.getCardId().toUpperCase());
        String key = RedisKeyEnum.REAL_NAME_SYSTEM_LOCK.getKey() + putCertificationRequest.getCardId();
        RLock lock = redisson.getLock(key);
        try {
            boolean res = lock.tryLock(3, TimeUnit.SECONDS);
            if (res) {
                SubmitRealNameVO submitRealNameVO = userInfoService.submitRealName(UserPool.getUser(), putCertificationRequest.getName(), putCertificationRequest.getCardId());
                return Result.success(submitRealNameVO);
            } else {
                return Result.fail(ErrorCode.LATER_TRY);
            }
        } catch (InterruptedException e) {
            return Result.fail("当前操作人数过多，请稍后再试");
        } finally {
            lock.unlock();
        }
    }

    @ApiOperation(value = "人脸核验", notes = "人脸核验", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/faceVerification", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<HwCheckVO> faceVerification(@Valid @RequestBody FaceVerificationRequest request) {
        return Result.success(userInfoService.verifyFace(UserPool.getUser(), request.getVideoBase64(), request.getActions()));
    }


    @ApiOperation(value = "人脸核验Url", notes = "人脸核验Url", httpMethod = "GET", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/faceVerificationUrl", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<String> faceVerificationUrl() {
        return Result.success(userInfoService.faceVerificationUrl(UserPool.getUser()));
    }


    @ApiOperation(value = "人脸核验回调", notes = "人脸核验回调", httpMethod = "POST")
    @PostMapping(value = "/faceVerificationCallBack")
    @WithoutSign
    public Result<ShuJuBaoFaceCheckVO> faceVerificationCallBack(ShuJuBaoLiveDetectionVO shuJuBaoLiveDetectionVO) {
        return Result.success(userInfoService.faceVerificationCallBack(shuJuBaoLiveDetectionVO));
    }


    @ApiOperation(value = "获取人脸回调是否为初始化状态", notes = "获取人脸回调是否为初始化状态", httpMethod = "POST")
    @PostMapping(value = "/faceGetInit")
    @UserLogin
    public Result<ShuJuBaoFaceGetInitVO> faceGetInit() {
        return Result.success(userInfoService.faceGetInit());
    }


    @ApiOperation(value = "我的页面", notes = "我的页面", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/getUserPage", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<UserPageVO> getUserPage() {
        return Result.success(userInfoService.getUserPage());
    }


    @ApiOperation(value = "我的页面->DAO", notes = "我的页面->DAO", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/getUserPageForDao", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<UserPageVO> getUserPageForDao(@Valid @RequestBody IdRequest request) {
        GetDaoByIdVO daoVO = userCreatorInfoDao.getDaoById(request.getId());
        if (ObjectUtil.isNull(daoVO) || daoVO.getStatus().intValue() != 1) {
            return Result.fail("该DAO不存在");
        }
        UserPageVO userPage = userInfoService.getUserPage();
        DaoIdentity maxIdentity = daoIdentityDao.getMaxIdentity(request.getId(), userPage.getUserId());
        if (ObjectUtil.isNotNull(maxIdentity)) {
            userPage.setDaoIdentityIcon(maxIdentity.getIdentityIcon());
        }
        return Result.success(userPage);
    }

    @ApiOperation(value = "我的收益详情", notes = "我的页面", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/getProfit", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<ProfitVO> getProfit() {
        return Result.success(userInfoService.getProfit(UserPool.getUser()));
    }


    @ApiOperation(value = "地图累计", notes = "地图累计", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/mapAccumulation", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<MapAccumulationVO> mapAccumulation() {
        return Result.success(userInfoService.mapAccumulation(UserPool.getUser()));
    }

    @ApiOperation(value = "地图累计收益详情", notes = "地图累计收益详情", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/mapAccumulationDetails", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public PageResult<MapAccumulationDetailsVO> mapAccumulationDetails(@RequestBody PageRequest pageRequest) {
        return PageResult.success(userInfoService.mapAccumulationDetails(pageRequest.toMp(), UserPool.getUser()));
    }

    @ApiOperation(value = "我的特权", notes = "我的特权", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/userPrivilege", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<UserPrivilegeVO> userPrivilege() {
        UserPrivilegeVO userPrivilegeVO = userInfoService.userPrivilege();
        return Result.success(userPrivilegeVO);
    }

//    @ApiOperation(value = "账号注销", notes = "账号注销", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
//    @PostMapping(value = "/accountCancellation", produces = MediaType.APPLICATION_JSON_VALUE)
//    @UserLogin
//    public Result accountCancellation(@Valid @RequestBody AccountCancellationRequest request) {
//
//        checkParameterService.CheckVerificationcode(request.getUserAccount(), request.getSmsId(), request.getCodes(), SendSMSEnum.ACCOUNT_CANCELLATION.getCode());
//
////        if (userRelevanceDao.shaolinTempleContractDisputes(218242L, UserPool.getUser().getId())) {
////            throw new GlobalRunTimeException("因政策原因,该账号禁止注销");
////        }
//        userInfoService.accountCancellation(request.getUserAccount(), request.getPwd());
//        return Result.success();
//    }

    @ApiOperation(value = "获取登陆手机号", notes = "获取登陆手机号", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/getUserTel", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<UserTelVO> getUserTel() {
        String userTel = UserPool.getUser().getUserTel();
        UserTelVO userTelVO = new UserTelVO();
        userTelVO.setUserTel(userTel);
        userTelVO.setUserUuid(UserPool.getUser().getUserUuid());
        return Result.success(userTelVO);
    }


    @ApiOperation(value = "查询邀请码", notes = "查询邀请码", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/findInviteCode", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<InviteUserVO> findInviteCode(@Valid @RequestBody InviteCodeRequest request) {
        UserInfo inviteUser = userInfoDao.getOneByInviteCode(request.getInviteCode());
        if (ObjectUtil.isEmpty(inviteUser)) {
            throw new GlobalRunTimeException(ErrorCode.BE_USER_IS_NOT_EXITS);
        }

        InviteUserVO inviteUserVO = new InviteUserVO();
        inviteUserVO.setUserTel(DesensitizedUtil.mobilePhone(inviteUser.getUserTel()));
        inviteUserVO.setAvatarImg(inviteUser.getAvatarImg());
        inviteUserVO.setNickName(inviteUser.getNickName());
        return Result.success(inviteUserVO);
    }

//    @ApiOperation(value = "绑定邀请码", notes = "绑定邀请码", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
//    @PostMapping(value = "/bindInviteCode", produces = MediaType.APPLICATION_JSON_VALUE)
//    @UserLogin
//    public Result bindInviteCode(@Valid @RequestBody InviteCodeRequest request) {
//        userInfoService.invite(UserPool.getUser(), request.getInviteCode());
//        return Result.success();
//    }

    @ApiOperation(value = "根据手机号获取用户基本信息", notes = "根据手机号获取用户基本信息", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/userTelGetUserInfo", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<UserTelGetUserInfoVO> userTelGetUserInfo(@RequestBody UserTelGetUserInfoDTO userTelGetUserInfoDTO) {
        UserTelGetUserInfoVO userTelGetUserInfoVO = userInfoDao.userTelGetUserInfo(userTelGetUserInfoDTO.getUserTel());
        if (BeanUtil.isEmpty(userTelGetUserInfoVO)) {
            throw new GlobalRunTimeException("用户不存在");
        }
        return Result.success(userTelGetUserInfoVO);
    }

    @ApiOperation(value = "用户是否是城主", notes = "用户创建群组", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/userIsCityMaster", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<Map> userIsCityMaster() {
        Map map = new HashMap();
        List<UserCollection> userCollections = userInfoService.userIsCityMaster();
        map.put("userIsCityMaster", !CollUtil.isEmpty(userCollections));
        TransferAccountsMinVO transferAccountsMinVO = new TransferAccountsMinVO();
        BeanUtil.copyProperties(staticDataDao.getByType("city_lord_product_id"), transferAccountsMinVO);
        map.put("userIsCityMasterId", transferAccountsMinVO);
        return Result.success(map);
    }


}